home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / progjrn / pj_6_1.arc / PJ5-2.ASM < prev    next >
Assembly Source File  |  1987-12-28  |  8KB  |  321 lines

  1. ; Program to illustrate high-speed text-drawing operation of
  2. ;  write mode 3 of the VGA.
  3. ;  Draws a string of 8x14 characters at arbitrary locations
  4. ;  without disturbing the background, using VGA's 8x14 ROM font.
  5. ;  Designed for use with modes 0Dh, 0Eh, 0Fh, 10h, and 12h.
  6. ; Runs only on VGAs (in Models 50 & up and IBM Display Adapter
  7. ;  and 100% compatibles).
  8. ; Assembled with MASM 4.0, linked with LINK 3.51.
  9. ; By Michael Abrash, 9/1/87.
  10. ; Page 22, Volume 6.1 Programmer's Journal
  11. ;
  12. stack    segment    para stack 'STACK'
  13.     db    512 dup(?)
  14. stack    ends
  15. ;
  16. VGA_VIDEO_SEGMENT    equ    0a000h    ;VGA display memory segment
  17. SCREEN_WIDTH_IN_BYTES    equ    044ah    ;offset of BIOS variable
  18. FONT_CHARACTER_SIZE    equ    14    ;# bytes in each font char
  19. ;
  20. ; VGA register equates.
  21. ;
  22. SC_INDEX    equ    3c4h    ;SC index register
  23. SC_MAP_MASK    equ    2    ;SC map mask register index
  24. GC_INDEX    equ    3ceh    ;GC index register
  25. GC_SET_RESET    equ    0    ;GC set/reset register index
  26. GC_ENABLE_SET_RESET equ    1    ;GC enable set/reset register index
  27. GC_ROTATE    equ    3    ;GC data rotate/logical function
  28.                 ; register index
  29. GC_MODE        equ    5    ;GC Mode register
  30. GC_BIT_MASK    equ    8    ;GC bit mask register index
  31. ;
  32. dseg    segment    para common 'DATA'
  33. TEST_TEXT_ROW    equ    69    ;row to display test text at
  34. TEST_TEXT_COL    equ    17    ;column to display test text at
  35. TEST_TEXT_COLOR    equ    0fh    ;high intensity white
  36. TestString    label    byte
  37.     db    'Hello, world!',0    ;test string to print.
  38. FontPointer    dd    ?        ;font offset
  39. dseg    ends
  40. ;
  41. cseg    segment    para public 'CODE'
  42.     assume    cs:cseg, ds:dseg
  43. start    proc    near
  44.     mov    ax,dseg
  45.     mov    ds,ax
  46. ;
  47. ; Select 640x480 graphics mode.
  48. ;
  49.     mov    ax,012h
  50.     int    10h
  51. ;
  52. ; Set the screen to all blue, using the readability of VGA registers
  53. ; to preserve reserved bits.
  54. ;
  55.     mov    dx,GC_INDEX
  56.     mov    al,GC_SET_RESET
  57.     out    dx,al
  58.     inc    dx
  59.     in    al,dx
  60.     and    al,0f0h
  61.     or    al,1        ;blue plane only set, others reset
  62.     out    dx,al
  63.     dec    dx
  64.     mov    al,GC_ENABLE_SET_RESET
  65.     out    dx,al
  66.     inc    dx
  67.     in    al,dx
  68.     and    al,0f0h
  69.     or    al,0fh        ;enable set/reset for all planes
  70.     out    dx,al
  71.     mov    dx,VGA_VIDEO_SEGMENT
  72.     mov    es,dx        ;point to display memory
  73.     mov    di,0
  74.     mov    cx,8000h     ;fill all 32k words
  75.     mov    ax,0ffffh    ;because of set/reset, the value
  76.                 ; written actually doesn't matter
  77.     rep stosw        ;fill with blue
  78. ;
  79. ; Set driver to use the 8x14 font.
  80. ;
  81.     mov    ah,11h    ;VGA BIOS character generator function,
  82.     mov    al,30h    ; return info subfunction
  83.     mov    bh,2    ;get 8x14 font pointer
  84.     int    10h
  85.     call    SelectFont
  86. ;
  87. ; Print the test string.
  88. ;
  89.     mov    si,offset TestString
  90.     mov    bx,TEST_TEXT_ROW
  91.     mov    cx,TEST_TEXT_COL
  92.     mov    ah,TEST_TEXT_COLOR
  93.     call    DrawString
  94. ;
  95. ; Wait for a key, then set to text mode & end.
  96. ;
  97.     mov    ah,1
  98.     int    21h    ;wait for a key
  99.     mov    ax,3
  100.     int    10h    ;restore text mode
  101. ;
  102. ; Exit to DOS.
  103. ;
  104.     mov    ah,4ch
  105.     int    21h
  106. Start    endp
  107. ;
  108. ; Subroutine to draw a text string left-to-right in a linear
  109. ;  graphics mode (0Dh, 0Eh, 0Fh, 010h, 012h) with 8-dot-wide
  110. ;  characters. Background around the pixels that make up the
  111. ;  characters is preserved.
  112. ; Font used should be pointed to by FontPointer.
  113. ;
  114. ; Input:
  115. ;  AH = color to draw string in
  116. ;  BX = row to draw string on
  117. ;  CX = column to start string at
  118. ;  DS:SI = string to draw
  119. ;
  120. ;  Forces ALU function to "move".
  121. ;  Forces write mode 3.
  122. ;
  123. DrawString    proc    near
  124.     push    ax
  125.     push    bx
  126.     push    cx
  127.     push    dx
  128.     push    si
  129.     push    di
  130.     push    bp
  131.     push    ds
  132. ;
  133. ; Set up set/reset to produce character color, using the readability
  134. ; of VGA register to preserve the setting of reserved bits 7-4.
  135. ;
  136.     mov    dx,GC_INDEX
  137.     mov    al,GC_SET_RESET
  138.     out    dx,al
  139.     inc    dx
  140.     in    al,dx
  141.     and    al,0f0h
  142.     and    ah,0fh
  143.     or    al,ah
  144.     out    dx,al
  145. ;
  146. ; Select write mode 3, using the readability of VGA registers
  147. ; to leave bits other than the write mode bits unchanged.
  148. ;
  149.     mov    dx,GC_INDEX
  150.     mov    al,GC_MODE
  151.     out    dx,al
  152.     inc    dx
  153.     in    al,dx
  154.     or    al,3
  155.     out    dx,al
  156.     mov    dx,VGA_VIDEO_SEGMENT
  157.     mov    es,dx            ;point to display memory
  158. ;
  159. ; Calculate screen address of byte character starts in.
  160. ;
  161.     push    ds    ;point to BIOS data segment
  162.     sub    dx,dx
  163.     mov    ds,dx
  164.     mov    di,ds:[SCREEN_WIDTH_IN_BYTES]    ;retrieve BIOS
  165.                         ; screen width
  166.     pop    ds
  167.     mov    ax,bx    ;row
  168.     mul    di    ;calculate offset of start of row
  169.     push    di    ;set aside screen width
  170.     mov    di,cx    ;set aside the column
  171.     and    cl,0111b ;keep only the column in-byte address
  172.     shr    di,1
  173.     shr    di,1
  174.     shr    di,1    ;divide column by 8 to make a byte address
  175.     add    di,ax    ;and point to byte
  176. ;
  177. ; Set up the GC rotation. In write mode 3, this is the rotation
  178. ; of CPU data before it is ANDed with the Bit Mask register to
  179. ; form the bit mask. Force the ALU function to "move". Uses the
  180. ; readability of VGA registers to leave reserved bits unchanged.
  181. ;
  182.     mov    dx,GC_INDEX
  183.     mov    al,GC_ROTATE
  184.     out    dx,al
  185.     inc    dx
  186.     in    al,dx
  187.     and    al,0e0h
  188.     or    al,cl
  189.     out    dx,al
  190. ;
  191. ; Set up BH as bit mask for left half, BL as rotation for right half.
  192. ;
  193.     mov    bx,0ffffh
  194.     shr    bh,cl
  195.     neg    cl
  196.     add    cl,8
  197.     shl    bl,cl
  198. ;
  199. ; Draw all characters, left portion first, then right portion in the
  200. ; succeeding byte, using the data rotation to position the character
  201. ; across the byte boundary and then using write mode 3 to combine the
  202. ; character data with the bit mask to allow the set/reset value (the
  203. ; character color) through only for the proper portion (where the
  204. ; font bits for the character are 1) of the character for each byte.
  205. ; Wherever the font bits for the character are 0, the background
  206. ; color is preserved.
  207. ; Does not check for case where character is byte-aligned and
  208. ; no rotation and only one write is required.
  209. ;
  210. ; Draw the left portion of each character in the string.
  211. ;
  212.     pop    cx    ;get back screen width
  213.     push    si
  214.     push    di
  215.     push    bx
  216. ;
  217. ; Set the bit mask for the left half of the character.
  218. ;
  219.     mov    dx,GC_INDEX
  220.     mov    al,GC_BIT_MASK
  221.     mov    ah,bh
  222.     out    dx,ax
  223. LeftHalfLoop:
  224.     lodsb
  225.     and    al,al
  226.     jz    LeftHalfLoopDone
  227.     call    CharacterUp
  228.     inc    di    ;point to next character location
  229.     jmp    LeftHalfLoop
  230. LeftHalfLoopDone:
  231.     pop    bx
  232.     pop    di
  233.     pop    si
  234. ;
  235. ; Draw the right portion of each character in the string.
  236. ;
  237.     inc    di    ;right portion of each character is across
  238.             ; byte boundary
  239. ;
  240. ; Set the bit mask for the right half of the character.
  241. ;
  242.     mov    dx,GC_INDEX
  243.     mov    al,GC_BIT_MASK
  244.     mov    ah,bl
  245.     out    dx,ax
  246. RightHalfLoop:
  247.     lodsb
  248.     and    al,al
  249.     jz    RightHalfLoopDone
  250.     call    CharacterUp
  251.     inc    di    ;point to next character location
  252.     jmp    RightHalfLoop
  253. RightHalfLoopDone:
  254. ;
  255.     pop    ds
  256.     pop    bp
  257.     pop    di
  258.     pop    si
  259.     pop    dx
  260.     pop    cx
  261.     pop    bx
  262.     pop    ax
  263.     ret
  264. DrawString    endp
  265. ;
  266. ; Draw a character.
  267. ;
  268. ; Input:
  269. ;  AL = character
  270. ;  CX = screen width
  271. ;  ES:DI = address to draw character at
  272. ;
  273. CharacterUp    proc    near
  274.     push    cx
  275.     push    si
  276.     push    di
  277.     push    ds
  278. ;
  279. ; Set DS:SI to point to font and ES to point to display memory.
  280. ;
  281.     lds    si,[FontPointer]    ;point to font
  282. ;
  283. ; Calculate font address of character.
  284. ;
  285.     mov    bl,14    ;14 bytes per character
  286.     mul    bl
  287.     add    si,ax    ;offset in font segment of character
  288.  
  289.     mov    bp,FONT_CHARACTER_SIZE
  290.     dec    cx    ; -1 because one byte per char
  291. CharacterLoop:
  292.     lodsb            ;get character byte
  293.     mov    ah,es:[di]    ;load latches
  294.     stosb            ;write character byte
  295. ;
  296. ; Point to next line of character in display memory.
  297. ;
  298.     add    di,cx
  299. ;
  300.     dec    bp
  301.     jnz    CharacterLoop
  302. ;
  303.     pop    ds
  304.     pop    di
  305.     pop    si
  306.     pop    cx
  307.     ret
  308. CharacterUp    endp
  309. ;
  310. ; Set the pointer to the font to draw from to ES:BP.
  311. ;
  312. SelectFont    proc    near
  313.     mov    word ptr [FontPointer],bp    ;save pointer
  314.     mov    word ptr [FontPointer+2],es
  315.     ret
  316. SelectFont    endp
  317. ;  
  318. cseg    ends
  319.     end    start
  320.  
  321.